#![cfg_attr(debug_assertions, allow(dead_code, unused_imports, unused_variables))]
mod parsing;
mod datatypes;
use serde_json::Value;
use std::fmt;
use crate::parsing::parse_abs_type;
#[derive(Debug)]
pub enum ProtocolError {
    TaskSignatureParseError(String),
    TypeSchemaParseError(String),
    InputFormatError(String),
    OutputFormatError(String),
    DataTypeError(String),
}
use ProtocolError::*;
impl ProtocolError {
    pub fn to_string(&self) -> String {
        match self {
            TaskSignatureParseError(s) => format!("任务签名解析错误: {}", s),
            TypeSchemaParseError(s) => format!("TypeSchema解析错误: {}", s),
            InputFormatError(s) => format!("任务输入格式错误: {}", s),
            OutputFormatError(s) => format!("任务输出格式错误: {}", s),
            DataTypeError(s) => format!("数据类型解析错误: {}", s),
        }
    }
}
#[derive(Debug, Clone, PartialEq)]
pub enum TypeSchema {
    Void,
    Int,
    Float,
    Str,
    Bool,
    Json,
    List(Box<TypeSchema>),
    Map(Box<TypeSchema>, Box<TypeSchema>),
    Tuple(Vec<TypeSchema>),
    Opt(Box<TypeSchema>),
    DataType(String),
}
impl TypeSchema {
    pub fn from_str(s: &str) -> Self {
        parse_abs_type(s).unwrap()
    }
    pub fn short_str(&self) -> String {
        match self {
            Self::Void => "Void".to_string(),
            Self::Int => "Int".to_string(),
            Self::Float => "Float".to_string(),
            Self::Str => "Str".to_string(),
            Self::Bool => "Bool".to_string(),
            Self::Json => "Json".to_string(),
            Self::List(inner) => format!("[{}]", inner.short_str()),
            Self::Map(key, value) => format!("Map<{}, {}>", key.short_str(), value.short_str()),
            Self::Tuple(inner) => format!("({})", inner.iter().map(|t| t.short_str()).collect::<Vec<String>>().join(", ")),
            Self::Opt(inner) => format!("?{}", inner.short_str()),
            Self::DataType(name) => name.clone(),
        }
    }
}
impl fmt::Display for TypeSchema {
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
        match self {
            TypeSchema::Void => write!(f, "Void"),
            TypeSchema::Int => write!(f, "Int"),
            TypeSchema::Float => write!(f, "Float"),
            TypeSchema::Str => write!(f, "String"),
            TypeSchema::Bool => write!(f, "Bool"),
            TypeSchema::Json => write!(f, "Json"),
            TypeSchema::List(inner) => write!(f, "List<{}>", inner),
            TypeSchema::Map(key, value) => write!(f, "Map<{}, {}>", key, value),
            TypeSchema::Tuple(inner) => write!(f, "({})", inner.iter().map(|t| t.to_string()).collect::<Vec<String>>().join(", ")),
            TypeSchema::Opt(inner) => write!(f, "?{}", inner),
            TypeSchema::DataType(name) => write!(f, "{}", name),
        }
    }
}
pub type NominalTask = String;
#[derive(Debug, PartialEq, Clone)]
pub struct TaskSignature {
    pub name: String,
    pub input_type: String,
    pub output_type: String,
}
#[derive(Debug, PartialEq, Clone)]
pub struct SymbolicTask {
    pub name: String,
    pub input_type: TypeSchema,
    pub output_type: TypeSchema,
}
impl SymbolicTask {
    pub fn new(name: String, input_type: TypeSchema, output_type: TypeSchema) -> Self {
        Self { name, input_type, output_type }
    }
    pub fn short_str(&self) -> String {
        format!("{}: {} -> {}", self.name, self.input_type.short_str(), self.output_type.short_str())
    }
    pub fn short_sig(&self) -> TaskSignature {
        TaskSignature { name: self.name.clone(), input_type: self.input_type.short_str(), output_type: self.output_type.short_str() }
    }
    pub fn sig(&self) -> TaskSignature {
        TaskSignature { name: self.name.clone(), input_type: self.input_type.to_string(), output_type: self.output_type.to_string() }
    }
}
impl fmt::Display for SymbolicTask {
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
        write!(f, "{}: {} -> {}", self.name, self.input_type, self.output_type)
    }
}
#[derive(Debug, Copy, Clone)]
pub enum TaskStatus {
    Created,
    Running,
    Completed,
    Failed,
    Stopped,
    Closed,
    ResultReceived,
    FailedToGetResult
}
#[derive(Debug, Clone)]
pub struct TaskProgressD {
    pub status: TaskStatus,
    pub percentage: f64,
    pub errmsg: Option<String>
}
#[derive(Debug)]
pub struct TaskInitD {
    pub task_id: String,
    pub progress_pipe_addr: String,
    pub log_pipe_addr: Option<String>,
    pub result_addr: String,
    pub instant_result: Option<Value>,
    pub status: Option<TaskStatus>,
    pub error_message: Option<String>
}
pub fn qualify(data: &Value, task: &TypeSchema) -> bool {
    true
}
#[derive(Debug, Clone, PartialEq)]
pub enum HealthyInfo {
    Healthy,
    Warn(String),
    Error(String)
}